﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NetworkManagement;

namespace LorraineSec.MessageLib.Messages
{
    public sealed class CreateLogMessage : EncryptedMessage
    {
        #region Format Constants
        /*
         * Format:
         *      4        4          4            4               2              2           x        y
         * | AssetID | UserID | DeviceID | CompartmentID | ContentLength | EventLength | Content | Event |
         */

        private const int ENC_ASSETID_LENGTH = 4;
        private const int ENC_USERID_LENGTH = 4;
        private const int ENC_DEVICEID_LENGTH = 4;
        private const int ENC_COMPID_LENGTH = 4;
        private const int ENC_CONTENTLEN_LENGTH = 2;
        private const int ENC_EVENTLEN_LENGTH = 2;

        private const int ENC_ASSETID_OFFSET = 0;
        private const int ENC_USERID_OFFSET = ENC_ASSETID_OFFSET + ENC_ASSETID_LENGTH;
        private const int ENC_DEVICEID_OFFSET = ENC_USERID_OFFSET + ENC_USERID_LENGTH;
        private const int ENC_COMPID_OFFSET = ENC_DEVICEID_OFFSET + ENC_DEVICEID_LENGTH;
        private const int ENC_CONTENTLEN_OFFSET = ENC_COMPID_OFFSET + ENC_COMPID_LENGTH;
        private const int ENC_EVENTLEN_OFFSET = ENC_CONTENTLEN_OFFSET + ENC_CONTENTLEN_LENGTH;
        private const int ENC_CONTENT_OFFSET = ENC_EVENTLEN_OFFSET + ENC_EVENTLEN_LENGTH;

        private const int ENC_KNOWN_LENGTH = ENC_ASSETID_LENGTH + ENC_USERID_LENGTH + ENC_DEVICEID_LENGTH + 
            ENC_COMPID_LENGTH + ENC_CONTENTLEN_LENGTH + ENC_EVENTLEN_LENGTH;
        #endregion

        public uint AssetID;
        public uint UserID;
        public uint DeviceID;
        public uint CompartmentID;
        public string EventContent;
        public string EventType;

        public CreateLogMessage()
        {
            init();
        }

        public CreateLogMessage(byte[] bytes)
            : base(bytes)
        {
            init();
            decode();
        }

        private void init()
        {
            MessageID = (ushort)LorraineSecMessageFactory.MessageID.CREATE_LOG;
        }

        public override void decrypt(CryptoManager crypt)
        {
            base.decrypt(crypt);
            AssetID = Bytes.getUInt32(encData, ENC_ASSETID_OFFSET);
            UserID = Bytes.getUInt32(encData, ENC_USERID_OFFSET);
            DeviceID = Bytes.getUInt32(encData, ENC_DEVICEID_OFFSET);
            CompartmentID = Bytes.getUInt32(encData, ENC_COMPID_OFFSET);
            ushort len = Bytes.getUInt16(encData, ENC_CONTENTLEN_OFFSET);
            EventContent = Bytes.getString(encData, ENC_CONTENT_OFFSET, len);
            len = Bytes.getUInt16(encData, ENC_EVENTLEN_OFFSET);
            EventType = Bytes.getString(encData, ENC_CONTENT_OFFSET + EventContent.Length, len);
        }

        public override void encrypt(CryptoManager crypt)
        {
            encData = new byte[ENC_KNOWN_LENGTH + EventContent.Length];
            Bytes.setValue(encData, ENC_ASSETID_OFFSET, AssetID);
            Bytes.setValue(encData, ENC_USERID_OFFSET, UserID);
            Bytes.setValue(encData, ENC_DEVICEID_OFFSET, DeviceID);
            Bytes.setValue(encData, ENC_COMPID_OFFSET, CompartmentID);
            Bytes.setValue(encData, ENC_CONTENTLEN_OFFSET, (ushort)EventContent.Length);
            Bytes.setValue(encData, ENC_EVENTLEN_OFFSET, (ushort)EventType.Length);
            Bytes.setValue(encData, ENC_CONTENT_OFFSET, EventContent);
            Bytes.setValue(encData, ENC_CONTENT_OFFSET + EventContent.Length, EventType);
            base.encrypt(crypt);
        }
    }
}
